/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.api.json;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.json.JSONObject;

import edu.cmu.lti.sepia.api.processor.AbstractProcessor;
import edu.cmu.lti.sepia.api.processor.AnswerProcessor;
import edu.cmu.lti.sepia.api.processor.IREvalProcessor;
import edu.cmu.lti.sepia.api.processor.LogProcessor;
import edu.cmu.lti.sepia.api.processor.NuggetProcessor;
import edu.cmu.lti.sepia.api.processor.PermissionProcessor;
import edu.cmu.lti.sepia.api.processor.ProgressProcessor;
import edu.cmu.lti.sepia.api.processor.QAEvalProcessor;
import edu.cmu.lti.sepia.api.processor.TaskProcessor;
import edu.cmu.lti.sepia.api.processor.TopicProcessor;
import edu.cmu.lti.sepia.api.processor.UserProcessor;
import edu.cmu.lti.sepia.api.processor.VoteProcessor;
import edu.cmu.lti.sepia.data.db.SQL;

@SuppressWarnings("serial")
public enum JsonAction {
	AddTask, GetTasks, GetTask, UpdateTask, DeleteTask,
	AddUser, GetUsers, GetUser, UpdateUser, DeleteUser,
	GetPermission,UpdatePermissions,
	UpdateDisplayLang,
	
	AddLog,
	UpdateProgress,
	
	GetTopic, GetTopics, AddTopic, UpdateTopic, DeleteTopic,
	
	AddAnswer, DeleteAnswer, UpdateAnswerText, UpdateAnswerLabel,
	AddNugget, DeleteNugget,
	UpdateVote,
	
	//Actually used
	IREvalPools, IREvalTopics, IREvalDocList, IREvalUpdate, IREvalGetDoc, 
	
	//???
	QAEvalPools, QAEvalTopics, QAEvalSystemResponses, QAEvalUpdate, QAEvalDone;
//	TopicBrief, QAEvalInsertDone, QAEvalDoneTopic, 
//	QAEvalPools, QAEvalAdditionalPools,  
//	QAEvalTopics, QAEvalMain, QAInsertMatched;
	
	// If this is not static, it's null when referred to by createJsonProcessor() 
	private static List<JsonAction> tasks = new ArrayList<JsonAction>(){{
		add( JsonAction.GetTasks );
		add( JsonAction.GetTask );
		add( JsonAction.AddTask );
		add( JsonAction.UpdateTask );
		add( JsonAction.DeleteTask );
	}};
	private static List<JsonAction> logs = new ArrayList<JsonAction>(){{
		add( JsonAction.AddLog );
	}};
	private static List<JsonAction> topics = new ArrayList<JsonAction>(){{
		add( JsonAction.GetTopic );
		add( JsonAction.GetTopics );
		add( JsonAction.AddTopic );
		add( JsonAction.UpdateTopic );
		add( JsonAction.DeleteTopic );
	}};
	private static List<JsonAction> answers = new ArrayList<JsonAction>(){{
		add( JsonAction.AddAnswer );
		add( JsonAction.DeleteAnswer );
		add( JsonAction.UpdateAnswerText );
		add( JsonAction.UpdateAnswerLabel );
	}};
	private static List<JsonAction> nuggets = new ArrayList<JsonAction>(){{
		add( JsonAction.AddNugget );
		add( JsonAction.DeleteNugget );
	}};
	private static List<JsonAction> users = new ArrayList<JsonAction>(){{
		add( JsonAction.AddUser );
		add( JsonAction.GetUsers );
		add( JsonAction.GetUser );
		add( JsonAction.UpdateUser );
		add( JsonAction.DeleteUser );
		add( JsonAction.UpdateDisplayLang );
	}};
	private static List<JsonAction> permissions = new ArrayList<JsonAction>(){{
		add( JsonAction.GetPermission );
		add( JsonAction.UpdatePermissions );
	}};
	private static List<JsonAction> progresses = new ArrayList<JsonAction>(){{
		add( JsonAction.UpdateProgress );
	}};
	private static List<JsonAction> votes = new ArrayList<JsonAction>(){{
		add( JsonAction.UpdateVote );
	}};
	private static List<JsonAction> irevals = new ArrayList<JsonAction>(){{
	  add( JsonAction.IREvalPools );
	  add( JsonAction.IREvalTopics );
	  add( JsonAction.IREvalDocList );
	  add( JsonAction.IREvalUpdate );
	  add( JsonAction.IREvalGetDoc );
	}};
	private static List<JsonAction> qaevals = new ArrayList<JsonAction>(){{
//	  add( JsonAction.TopicBrief );
	  add( JsonAction.QAEvalPools );
	  add( JsonAction.QAEvalTopics );
	  add( JsonAction.QAEvalSystemResponses );
	  add( JsonAction.QAEvalUpdate );
	  add( JsonAction.QAEvalDone );
	  
//	  add( JsonAction.QAEvalAdditionalPools );
//	  add( JsonAction.QAEvalTopics );
//	  add( JsonAction.QAEvalMain );
//	  add( JsonAction.QAInsertMatched );
//	  add( JsonAction.QAEvalInsertDone );
//	  add( JsonAction.QAEvalDoneTopic );
	}};
//	private static List<JsonAction> qaevals = new ArrayList<JsonAction>(){{
//		add( JsonAction.TopicBrief );
//		add( JsonAction.QAEvalPools );
//		add( JsonAction.QAEvalAdditionalPools );
//		add( JsonAction.QAEvalTopics );
//		add( JsonAction.QAEvalMain );
//		add( JsonAction.QAInsertMatched );
//		add( JsonAction.QAEvalInsertDone );
//		add( JsonAction.QAEvalDoneTopic );
//	}};
	
	private AbstractProcessor createJsonProcessor() {
		AbstractProcessor processor = null;
		if ( contains(tasks,this) ) {
			processor = new TaskProcessor();
		} else if ( contains(users,this) ) {
			processor = new UserProcessor();
		} else if ( contains(permissions,this) ) {
			processor = new PermissionProcessor();
		} else if ( contains(progresses,this) ) {
			processor = new ProgressProcessor();
		} else if ( contains(logs,this) ) {
			processor = new LogProcessor();
		} else if ( contains(topics,this) ) {
			processor = new TopicProcessor();
		} else if ( contains(answers,this) ) {
			processor = new AnswerProcessor();
		} else if ( contains(nuggets,this) ) {
			processor = new NuggetProcessor();
		} else if ( contains(votes,this) ) {
			processor = new VoteProcessor();
		} else if ( contains(qaevals,this) ) {
			processor = new QAEvalProcessor();
		} else if ( contains(irevals,this) ) {
      processor = new IREvalProcessor();
		}
		return processor;
	}
	
	private boolean contains( List<JsonAction> actions, JsonAction action ) {
		for ( JsonAction a : actions ) {
			if ( a.toString().equals(action.toString()) ) return true; 
		}
		return false;
	}
	
	public JSONObject execute( SQL sql, HttpServletRequest request ) {
		AbstractProcessor processor = this.createJsonProcessor();
		return processor.process(sql, this, request);
	}
	
}
